//
//  SQLiteDB.m
//  fit_mbcreater
//
//  Created by Feng Huajun on 07-9-19, adapted by Andreas Schwelling on 21.11.2007.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "SQLiteDB.h"
#import <stdlib.h>

@implementation SQLiteDB



-(SQLiteDB *) initWithPath: (NSString*)path
{
	self = [super init];
	if (self != nil) {
		int err = sqlite3_open([path fileSystemRepresentation], &db);
		if (err) {
			NSLog(@"can not open database:%@",path);
			exit(1);
		}
	}
	return self;
}

-(void) enableQueryCache
{
	if(!queryCache){
		queryCacheRowNum = 1000;
		queryCache = [[NSMutableDictionary alloc] init];
	}
}

-(NSArray*) query: (NSString *)sql
{
	NSString* key = nil;
	if(queryCache){
		key = sql;
		NSArray* cacheRows = [queryCache objectForKey:key];
		if(cacheRows) {
			//NSLog(@"cache hitted");
			return cacheRows;
		}
	}
	//NSLog(@"query: %@",sql);
	char* errMsg;
	char **result;
	int nrow,ncol;
	int err = sqlite3_get_table(db,[sql UTF8String],&result,&nrow,&ncol,&errMsg);
	if( err != SQLITE_OK ){
		NSLog(@"query sql error! sql:%@ message:%s", sql, errMsg);
		exit(1);		
	}
	
	NSMutableArray* rows = [[NSMutableArray alloc] initWithCapacity:nrow];
	[rows autorelease];
	
	
	
	if(nrow != 0) {
		
		NSMutableArray* colNames = [[NSMutableArray alloc] initWithCapacity: ncol];
		
		int idx = 0;
		int i,j;
		
		for(i = 0; i < ncol; i++){
			NSString* s = [[NSString alloc] initWithUTF8String:result[i]];
			[colNames addObject:s];
			[s release];
		}
		
		for(i = 0; i < nrow; i++ ) {
			NSMutableDictionary* cols = [[NSMutableDictionary alloc] initWithCapacity: ncol];
			for(j=0;j<ncol;j++){
				idx = (i+1)*ncol + j;
				//printf("s=%s\n",result[idx]);
				
				if(result[idx]){
					NSString* s = [[NSString alloc] initWithUTF8String:result[idx]];
					//if (s==nil) s=@"";
					[cols setObject:s forKey:[colNames objectAtIndex:j]];
					[s release];
				}else{
					[cols setObject:@"" forKey:[colNames objectAtIndex:j]];
				}
				
				
			}
			[rows addObject:cols];
			[cols release];
		}
		[colNames release];
	}
	
	sqlite3_free_table(result);
	
	if(queryCache){
		if([queryCache count] > queryCacheRowNum){
			[queryCache release];
			queryCache = [[NSMutableDictionary alloc] init];
		}
		[queryCache setObject:rows forKey:key];
	}
	
	return rows;
}

-(NSArray*) queryGBK: (NSString *)sql
{
	NSString* key = nil;
	if(queryCache){
		key = sql;
		NSArray* cacheRows = [queryCache objectForKey:key];
		if(cacheRows) {
			//NSLog(@"cache hitted");
			return cacheRows;
		}
	}
	//NSLog(@"query: %@",sql);
	char* errMsg;
	char **result;
	int nrow,ncol;
	int err = sqlite3_get_table(db,[sql UTF8String],&result,&nrow,&ncol,&errMsg);
	if( err != SQLITE_OK ){
		NSLog(@"query sql error! sql:%@ message:%s", sql, errMsg);
		exit(1);		
	}
	
	NSMutableArray* rows = [[NSMutableArray alloc] initWithCapacity:nrow];
	[rows autorelease];
	
	
	
	if(nrow != 0) {
		
		NSMutableArray* colNames = [[NSMutableArray alloc] initWithCapacity: ncol];
		
		int idx = 0;
		int i,j;
		
		for(i = 0; i < ncol; i++){
			NSString* s = [[NSString alloc] initWithUTF8String:result[i]];
			[colNames addObject:s];
			[s release];
		}
		
		for(i = 0; i < nrow; i++ ) {
			NSMutableDictionary* cols = [[NSMutableDictionary alloc] initWithCapacity: ncol];
			for(j=0;j<ncol;j++){
				idx = (i+1)*ncol + j;
				//printf("s=%s\n",result[idx]);
				/*NSLog(@"============BEGIN AGAIN==========");
				 if(result[idx]){
				 NSString* s = [[NSString alloc] initWithUTF8String:result[idx]];
				 NSLog(@"s value:%@",s);
				 [cols setObject:s forKey:[colNames objectAtIndex:j]];
				 [s release];
				 }else{
				 [cols setObject:@"" forKey:[colNames objectAtIndex:j]];
				 }*/
				
				
				if(result[idx]){
					const char *s = result[idx];
					
					
					CFStringRef *str = CFStringCreateWithBytes( NULL, s, strlen(s), kCFStringEncodingGB_18030_2000, false);
					if ( str == NULL ) {
						NSLog(@"Create string failed! Not a GB2312 string." );
						//Now we try to convert it to UTF8 string.
						str = CFStringCreateWithBytes( NULL, s, strlen(s), kCFStringEncodingUTF8, false );
						
						//NSLog(@"Now we try to convert it to UTF8 string.");
						
						if ( str == NULL ) {
							NSLog(@"Not a UTF8 string , must be error!" );
						}
						else {
							[cols setObject:(NSString*)str forKey:[colNames objectAtIndex:j]];
							NSLog(@"str value:%@",str);
							
							CFRelease(str);
						}
					}
					else {
						[cols setObject:(NSString*)str forKey:[colNames objectAtIndex:j]];
						CFRelease(str);
					}
				}else{
					[cols setObject:@"" forKey:[colNames objectAtIndex:j]];
				}
			}
			[rows addObject:cols];
			[cols release];
		}
		[colNames release];
	}
	
	sqlite3_free_table(result);
	
	if(queryCache){
		if([queryCache count] > queryCacheRowNum){
			[queryCache release];
			queryCache = [[NSMutableDictionary alloc] init];
		}
		[queryCache setObject:rows forKey:key];
	}
	
	return rows;
}

-(void) execute: (NSString *)sql
{
	char* errMsg;
	int err = sqlite3_exec(db,[sql UTF8String], NULL, 0, &errMsg);
	if(err!=SQLITE_OK){
        NSLog(@"excute sql error! sql:%@ message:%s", sql, errMsg);
        exit(1);	
	}
}

- (void) dealloc
{
	if(queryCache) [queryCache release];
	sqlite3_close(db);
	[super dealloc];
}


@end
